package com.gaogzhen.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gaogzhen.domain.Market;
import com.gaogzhen.domain.UserFavoriteMarket;
import com.gaogzhen.dto.TradeAreaDto;
import com.gaogzhen.mappers.TradeAreaDtoMappers;
import com.gaogzhen.model.RRException;
import com.gaogzhen.service.MarketService;
import com.gaogzhen.service.UserFavoriteMarketService;
import com.gaogzhen.vo.MergeDeptVo;
import com.gaogzhen.vo.TradeAreaMarketsVo;
import com.gaogzhen.vo.TradeMarketVo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gaogzhen.mapper.TradeAreaMapper;
import com.gaogzhen.domain.TradeArea;
import com.gaogzhen.service.TradeAreaService;
/**
* @author Administrator
* @date 2022-12-08 10:18
*/
@Service
public class TradeAreaServiceImpl extends ServiceImpl<TradeAreaMapper, TradeArea> implements TradeAreaService{

    @Autowired
    private MarketService marketService;

    @Autowired
    private UserFavoriteMarketService userFavoriteMarketService;

    @Override
    public Page<TradeArea> findByPage(Page<TradeArea> page, String name, Byte status) {
        return page(page, new LambdaQueryWrapper<TradeArea>()
                            .eq(status != null, TradeArea::getStatus, status)
                            .like(StringUtils.isNotEmpty(name), TradeArea::getName, name)
        );
    }

    @Override
    public void updateStatus(Long id, Byte status) {
        boolean update = update(new LambdaUpdateWrapper<TradeArea>()
                .eq(TradeArea::getId, id)
                .set(TradeArea::getStatus, status));
        if (!update) {
            throw new RRException("更改状态失败");
        }
    }

    @Override
    public List<TradeArea> findAll(Byte status) {
        return list(new LambdaQueryWrapper<TradeArea>().eq(TradeArea::getStatus, status));
    }

    @Override
    public List<TradeAreaMarketsVo> getTradeAreaMarkets() {
        // 1 查询校验区域
        List<TradeArea> tradeAreas = list(new LambdaQueryWrapper<TradeArea>().eq(TradeArea::getStatus, 1).orderByAsc(TradeArea::getSort));
        if (CollectionUtils.isEmpty(tradeAreas)) {
            return Collections.emptyList();
        }
        // 2 查询交易区域包含的交易市场
        List<Long> ids = tradeAreas.stream().map(TradeArea::getId).collect(Collectors.toList());
        Map<Long, List<Market>> marketMap =  marketService.getMarketsByTradeAreaId(ids);
        // 3 构建TradeAreaMarketsVo集合
        List<TradeAreaMarketsVo> tradeAreaMarketsVos = new ArrayList<>();
        for (TradeArea tradeArea : tradeAreas) {
            TradeAreaMarketsVo tradeAreaMarketsVo = new TradeAreaMarketsVo();
            tradeAreaMarketsVo.setAreaName(tradeArea.getName());
            List<Market> markets = marketMap.get(tradeArea.getId());
            if (CollectionUtils.isNotEmpty(markets)) {
                tradeAreaMarketsVo.setMarkets(markets2Vo(markets));
            }
            tradeAreaMarketsVos.add(tradeAreaMarketsVo);
        }
        return tradeAreaMarketsVos;
    }

    @Override
    public List<TradeAreaMarketsVo> getUserFavoriteMarkets(Long userId) {
        // 1 查询用户收藏的marketIds
        List<UserFavoriteMarket> favoriteMarkets = userFavoriteMarketService.list(new LambdaQueryWrapper<UserFavoriteMarket>().eq(UserFavoriteMarket::getUserId, userId));
        if (CollectionUtils.isEmpty(favoriteMarkets)) {
            return Collections.emptyList();
        }
        List<Long> marketsId = favoriteMarkets.stream().map(UserFavoriteMarket::getMarketId).collect(Collectors.toList());
        TradeAreaMarketsVo tradeAreaMarketsVo = new TradeAreaMarketsVo();
        tradeAreaMarketsVo.setAreaName("自选");
        List<Market> markets = marketService.listByIds(marketsId);
        tradeAreaMarketsVo.setMarkets(markets2Vo(markets));
        return Collections.singletonList(tradeAreaMarketsVo);
    }

    @Override
    public List<TradeAreaDto> findAllTradeAreaAndMarket() {
        List<TradeArea> tradeAreas = findAll((byte) 1);
        List<TradeAreaDto> tradeAreaDtoList = TradeAreaDtoMappers.INSTANCE.toConvertDto(tradeAreas);
        if(org.springframework.util.CollectionUtils.isEmpty(tradeAreaDtoList)){
            for (TradeAreaDto tradeAreaDto : tradeAreaDtoList) {
                List<Market> markets = marketService.queryByAreaId(tradeAreaDto.getId()) ;
                if(!org.springframework.util.CollectionUtils.isEmpty(markets)){
                    String marketIds = markets.stream().map(market -> market.getId().toString()).collect(Collectors.joining(","));
                    tradeAreaDto.setMarketIds(marketIds);
                }

            }
        }
        return tradeAreaDtoList;
    }

    private List<TradeMarketVo> markets2Vo(List<Market> markets) {
        return markets.stream().map(this::convert2Vo).collect(Collectors.toList());
    }

    private TradeMarketVo convert2Vo(Market market) {
        TradeMarketVo tradeMarketVo = new TradeMarketVo();
        tradeMarketVo.setImage(market.getImg());
        tradeMarketVo.setName(market.getName());
        tradeMarketVo.setSymbol(market.getSymbol());

        // 价格
        tradeMarketVo.setHigh(market.getOpenPrice());
        tradeMarketVo.setLow(market.getOpenPrice());
        tradeMarketVo.setPrice(market.getOpenPrice());
        tradeMarketVo.setCnyPrice(market.getOpenPrice());
        tradeMarketVo.setCoinCnyPrice(market.getOpenPrice());
        String name = market.getName();
        String s = name.split("/")[0];
        tradeMarketVo.setPriceUnit(s);
        // 交易量
        tradeMarketVo.setAmount(BigDecimal.ZERO);
        tradeMarketVo.setVolume(BigDecimal.ZERO);

        // 涨跌幅
        tradeMarketVo.setChange(0);

        // 交易额度
        tradeMarketVo.setTradeMax(market.getTradeMax());
        tradeMarketVo.setTradeMin(market.getTradeMin());
        // 下单的数量限制
        tradeMarketVo.setNumMax(market.getNumMax());
        tradeMarketVo.setNumMin(market.getNumMin());
        // 手续费
        tradeMarketVo.setBuyFeeRate(market.getFeeBuy());
        tradeMarketVo.setSellFeeRate(market.getFeeSell());
        // 价格小数位数
        tradeMarketVo.setNumScale(market.getNumScale());
        // 排序
        tradeMarketVo.setSort(market.getSort());
        // 合并深度
        tradeMarketVo.setMergeDepth(getMergeDepths(market.getMergeDepth()));

        return tradeMarketVo;
    }

    private List<MergeDeptVo> getMergeDepths(String mergeDepth) {
        String[] depths = mergeDepth.split(",");
        Arrays.sort(depths);
        if (depths.length != 3) {
            throw new RRException("合并深度不合法");
        }
        List<MergeDeptVo> mergeDeptVos = new ArrayList<>(3);
        MergeDeptVo mergeDeptVo1 = new MergeDeptVo();
        mergeDeptVo1.setMergeType("MIN");
        mergeDeptVo1.setValue(calVal(depths[0]));
        MergeDeptVo mergeDeptVo2 = new MergeDeptVo();
        mergeDeptVo2.setMergeType("DEFAULT");
        mergeDeptVo2.setValue(calVal(depths[1]));
        MergeDeptVo mergeDeptVo3 = new MergeDeptVo();
        mergeDeptVo3.setMergeType("MAX");
        mergeDeptVo3.setValue(calVal(depths[2]));
        mergeDeptVos.add(mergeDeptVo1);
        mergeDeptVos.add(mergeDeptVo2);
        mergeDeptVos.add(mergeDeptVo3);
        return mergeDeptVos;
    }

    private BigDecimal calVal(String depth) {
        int k = Integer.parseInt(depth);
        BigDecimal bigDecimal = BigDecimal.valueOf(Math.pow(10, k));
        return BigDecimal.ONE.divide(bigDecimal).setScale(k, RoundingMode.HALF_UP);
    }
}
